#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>

void type(struct stat st){
    //判断文件类型
    switch(st.st_mode & __S_IFMT){
        case  __S_IFDIR://目录
            printf("d");
            break;
        case  __S_IFCHR://字符设备
            printf("C");
            break;
        case  __S_IFREG://普通文件
            printf("-");
            break;
        case  __S_IFLNK://链接文件
            printf("l");
            break;
        case  __S_IFIFO://管道文件
            printf("p");
            break;
        case  __S_IFSOCK://套接字文件
            printf("s");
            break;
    }
}

void permissions(struct stat st){
    //判断文件权限
    //用户
    if(st.st_mode & S_IRUSR){
        printf("r");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IWUSR){
        printf("w");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IXUSR){
        printf("x");
    }else{
        printf("-");
    }

    //组
    if(st.st_mode & S_IRGRP){
        printf("r");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IWGRP){
        printf("w");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IXGRP){
        printf("x");
    }else{
        printf("-");
    }

    //其他
    if(st.st_mode & S_IROTH){
        printf("r");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IWOTH){
        printf("w");
    }else{
        printf("-");
    }

    if(st.st_mode & S_IXOTH){
        printf("x");
    }else{
        printf("-");
    }
} 


int main(int argc ,char const *argv[]){

    DIR* dir = opendir(".");
    if(NULL == dir){
        perror("opendir err");
        return -1; 
    }




    
    struct dirent* d=NULL;
    while((d = readdir(dir)) != NULL){
        struct stat st;
        

        if(d->d_name[0] != '.'){

            if(stat(d->d_name,&st) < 0){
                perror("stat err");
                return -1;
            }
            type(st);
            permissions(st);
            printf(" %lu",st.st_nlink);

            //用户名
            struct passwd* user;
            user=getpwuid(st.st_uid);
            if(user == NULL){
                return -1;
            }
            printf(" %s",user->pw_name);
            //组名
            struct group* gro;
            gro=getgrgid(st.st_gid);
            if(gro == NULL){
                return -1;
            }
            printf(" %-*s",6,gro->gr_name);

            //字节数
            printf(" %*lu",6,st.st_size);

            //最近一次修改时间
            char* ch=NULL;
            ch=ctime(&(st.st_mtime));
            ch[strlen(ch)-1]=0;
            printf(" %-*s",5,ch);
            

            printf(" %-*s\n",9,d->d_name);
        }
    }

    closedir(dir);
    return 0;
}